using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content.Pipeline;
using Microsoft.Xna.Framework.Content.Pipeline.Graphics;
using Microsoft.Xna.Framework.Content.Pipeline.Processors;
using LevelData;

// TODO: replace these with the processor input and output types.
using TInput = System.String;
using TOutput = LevelData.Level;

namespace LevelPipeline
{
    /// <summary>
    /// This class will be instantiated by the XNA Framework Content Pipeline
    /// to apply custom processing to content data, converting an object of
    /// type TInput to TOutput. The input and output types may be the same if
    /// the processor wishes to alter data without changing its type.
    ///
    /// This should be part of a Content Pipeline Extension Library project.
    ///
    /// TODO: change the ContentProcessor attribute to specify the correct
    /// display name for this processor.
    /// </summary>
    [ContentProcessor(DisplayName = "LevelProcessor")]
    public class ContentProcessor : ContentProcessor<TInput, TOutput>
    {
        private int countTiles;
        public override TOutput Process(TInput input, ContentProcessorContext context)
        {
            // TODO: process the input object, and return the modified data.
            Level lvl = new Level();
            
            char[] p = input.ToCharArray();

            lvl.ObjectList.Clear();
            lvl.platformList.Clear();
            lvl.enemyList.Clear();
            lvl.blockList.Clear();

            Random rand = new Random();
            int posX = 0;
            int posY = 0;

            lvl.numLevel = (int)p[0] - 48;

            lvl.storyMode = true;

            Random roll = new Random();
            int numberType = (int)p[1] - 48; //roll.Next() % 7;
            for (int i = 2; i < p.Count(); i++)
            {
                if (p[i] == '#')
                {
                    lvl.blockList.Add(new block(posX, posY, numberType));
                    lvl.tiles.Add(new Tile(LevelData.TileCollision.Impassable));
                    posX++;
                }
                else if (p[i] == '-')
                {
                    lvl.platformList.Add(new platform(posX,posY));
                    lvl.tiles.Add(new Tile(LevelData.TileCollision.Platform));
                    posX++;
                }
                else if (p[i] == 'G')
                {
                    lvl.ObjectList.Add(new ObjGame(posX, posY, ObjectType.Gold));
                    lvl.tiles.Add(new Tile(LevelData.TileCollision.Passable));
                    posX++;
                }
                else if (p[i] == 'M')
                {
                    lvl.ObjectList.Add(new ObjGame(posX, posY, ObjectType.Money));
                    lvl.tiles.Add(new Tile(LevelData.TileCollision.Passable));
                    posX++;
                }
                else if (p[i] == 'H')
                {
                    lvl.ObjectList.Add(new ObjGame(posX, posY, ObjectType.PoisonHealt));
                    lvl.tiles.Add(new Tile(LevelData.TileCollision.Passable));
                    posX++;
                }
                else if (p[i] == 'S')
                {
                    lvl.ObjectList.Add(new ObjGame(posX, posY, ObjectType.Star));
                    lvl.tiles.Add(new Tile(LevelData.TileCollision.Passable));
                    posX++;
                }
                else if (p[i] == 'L')
                {
                    lvl.ObjectList.Add(new ObjGame(posX, posY, ObjectType.PoisonHealtPlus));
                    lvl.tiles.Add(new Tile(LevelData.TileCollision.Passable));
                    posX++;
                }
                else if (p[i] == 'D')
                {
                    lvl.ObjectList.Add(new ObjGame(posX, posY, ObjectType.DoorA));
                    lvl.tiles.Add(new Tile(LevelData.TileCollision.Impassable));
                    posX++;
                }
                else if (p[i] == 'd')
                {
                    lvl.ObjectList.Add(new ObjGame(posX, posY, ObjectType.OpenDoorA));
                    lvl.tiles.Add(new Tile(LevelData.TileCollision.Passable));
                    posX++;
                }
                else if (p[i] == 'Q')
                {
                    lvl.ObjectList.Add(new ObjGame(posX, posY, ObjectType.DoorB));
                    lvl.tiles.Add(new Tile(LevelData.TileCollision.Impassable));
                    posX++;
                }
                else if (p[i] == 'q')
                {
                    lvl.ObjectList.Add(new ObjGame(posX, posY, ObjectType.OpenDoorB));
                    lvl.tiles.Add(new Tile(LevelData.TileCollision.Passable));
                    posX++;
                }
                else if (p[i] == 'W')
                {
                    lvl.ObjectList.Add(new ObjGame(posX, posY, ObjectType.DoorC));
                    lvl.tiles.Add(new Tile(LevelData.TileCollision.Impassable));
                    posX++;
                }
                else if (p[i] == 'w')
                {
                    lvl.ObjectList.Add(new ObjGame(posX, posY, ObjectType.OpenDoorC));
                    lvl.tiles.Add(new Tile(LevelData.TileCollision.Passable));
                    posX++;
                }
                else if (p[i] == '0')
                {
                    lvl.ObjectList.Add(new ObjGame(posX, posY, ObjectType.CheckPoint));
                    lvl.tiles.Add(new Tile(LevelData.TileCollision.Passable));
                    posX++;
                }
                else if (p[i] == 'A')
                {
                    ColorEnemy color;
                    switch (rand.Next(3))
                    {
                        case 0:
                            color = ColorEnemy.Yellow;
                            break;
                        case 1:
                            color = ColorEnemy.Red;
                            break;
                        case 2:
                            color = ColorEnemy.Green;
                            break;
                        default:
                            color = ColorEnemy.Yellow;
                            break;
                    }

                    lvl.enemyList.Add(new Enemy(posX, posY, EnemyType.Monster, color));
                    lvl.tiles.Add(new Tile(LevelData.TileCollision.Passable));
                    posX++;
                }
                else if (p[i] == 'B')
                {
                    lvl.enemyList.Add(new Enemy(posX, posY, EnemyType.Thorns, ColorEnemy.noColor));
                    lvl.tiles.Add(new Tile(LevelData.TileCollision.Passable)); 
                    posX++;
                }
                else if (p[i] == 'C')
                {
                    lvl.enemyList.Add(new Enemy(posX, posY, EnemyType.Guillottine, ColorEnemy.noColor));
                    lvl.tiles.Add(new Tile(LevelData.TileCollision.Passable));
                    posX++;
                }
                else if (p[i] == '1')
                {
                    lvl.playerLevel = new player(posX, posY);
                    lvl.tiles.Add(new Tile(LevelData.TileCollision.Passable));
                    posX++;
                }
                else if (p[i] == 'X')
                {
                    lvl.ObjectList.Add(new ObjGame(posX, posY, ObjectType.Exit));
                    lvl.tiles.Add(new Tile(LevelData.TileCollision.Passable));
                    posX++;
                }
                else if (p[i] == 'x')
                {
                    lvl.ObjectList.Add(new ObjGame(posX, posY, ObjectType.openExit));
                    lvl.tiles.Add(new Tile(LevelData.TileCollision.Passable));
                    posX++;
                }
                else if (p[i] == '.')
                {
                    lvl.tiles.Add(new Tile(LevelData.TileCollision.Passable));
                    posX++;
                }
                else if (p[i] == '\r')
                {
                    countTiles = posX;
                    posX = 0;
                    posY++;
                }

            }

            lvl.lenghtX = countTiles;
            lvl.lenghtY = posY+1;

            return lvl;
        }
    }
}